package com.yds.developtools.utils

import android.app.AlarmManager
import android.app.Application
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Environment
import android.os.Process
import android.util.Log
import java.io.*
import kotlin.system.exitProcess


/**
 * 作者:     YDS
 * 创建时间: 2025/3/27 16:45
 * 页面描述: 闪退捕捉帮助类
 */
@Suppress("unused")
object YDSCrashCatchHelper {

    /**
     * 初始化闪退捕捉
     * @param application 全局上下文
     * @param logPath 日志路径，默认/sdcard/包名/Logs/
     * @param logName 日志名称
     * @param autoRestart 是否自动重启-默认false
     *
     * use: YDSCrashCatchHelper.init(this, null, null)
     */
    fun init(application: Application, autoRestart: Boolean = false, logName: String? = null, logPath: String? = null) {
        object : Thread() {
            override fun run() {
                Log.i("YDSCrashCatchHelper", "init application = $application")
                try {
                    val process = Runtime.getRuntime().exec("logcat -v time *:I --pid=" + Process.myPid())
                    var os: BufferedWriter? = null
                    var mLine: String
                    try {
                        val mReader = BufferedReader(InputStreamReader(process.inputStream))
                        // 日志路径
                        val packageName = application.packageName
                        var logAbsolutePathTemp: String = Environment.getExternalStorageDirectory().absolutePath + File.separator + packageName + File.separator + "Logs" + File.separator
                        logPath?.let {
                            logAbsolutePathTemp = logPath
                        }
                        val folder = File(logAbsolutePathTemp)
                        if (!folder.exists()) {
                            folder.mkdirs()
                        }
                        // 日志名称
                        var logNameTemp = "CrashLog.txt"
                        logName?.let {
                            logNameTemp = logName
                        }
                        os = BufferedWriter(FileWriter(logAbsolutePathTemp + File.separator + logNameTemp, true))

                        while (mReader.readLine().also { mLine = it } != null) {
                            if (mLine.contains("Exception:") || mLine.contains("AndroidRuntime")) {
                                os.write("$mLine\n")
                                os.flush()
                                if (mLine.contains(packageName) && (mLine.contains(".kt:") || mLine.contains(".java:"))) {
                                    if (autoRestart) {
                                        restartApp(application)
                                    }
                                }
                            }
                        }
                    } catch (_: Exception) {
                    } finally {
                        if (os != null) {
                            try {
                                os.close()
                            } catch (_: IOException) {
                            }
                        }
                    }
                } catch (_: Exception) {
                } finally {
                }
            }
        }.start()
    }

    /**
     * 重启应用
     * @param application 全局上下文
     */
    fun restartApp(application: Application) {
        val intent = application.packageManager.getLaunchIntentForPackage(application.packageName)
        if (intent != null) {
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
            val pendingIntent = PendingIntent.getActivity(application, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE)
            val alarmManager = application.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            alarmManager.set(AlarmManager.RTC, System.currentTimeMillis(), pendingIntent)
            Process.killProcess(Process.myPid())
            exitProcess(0)
        }
    }

    /**
     * 捕捉闪退信息
     * @return callback 具体的异常信息
     *
     * use: YDSCrashCatchHelper.catchMessage {}
     */
    fun catchMessage(callback: (String) -> Unit) {
        object : Thread() {
            override fun run() {
                try {
                    val process = Runtime.getRuntime().exec("logcat -v time *:I --pid=" + Process.myPid())
                    var mLine: String
                    try {
                        val mReader = BufferedReader(InputStreamReader(process.inputStream))
                        while (mReader.readLine().also { mLine = it } != null) {
                            if (mLine.contains("Exception:") || mLine.contains("AndroidRuntime")) {
                                callback(mLine)
                            }
                        }
                    } catch (_: Exception) {
                    }
                } catch (_: Exception) {
                }
            }
        }.start()
    }

}